﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using MugenMvvmToolkit.Infrastructure;
using Should;

namespace MugenMvvmToolkitTest.Infrastructure
{
    [TestClass]
    public class WeakReferenceCollectionTest : CollectionTestBase
    {
        [TestMethod]
        public void WeakReferenceOneItemTest()
        {
            var item = new Item();
            var collection = new WeakReferenceCollection<Item>();
            collection.Add(item);
            collection.Contains(item).ShouldBeTrue();

            item = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            collection.Count.ShouldEqual(0);
        }

        [TestMethod]
        public void WeakReferenceCollectionItemTest()
        {
            var items = new[] {new Item(), new Item(), new Item(), new Item(),};
            var collection = new WeakReferenceCollection<Item>(items);
            collection.Count.ShouldEqual(items.Length);

            items[0] = null;
            items[1] = null;
            items[2] = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            collection.Count.ShouldEqual(1);
            collection.Contains(items[3]).ShouldBeTrue();
        }

        [TestMethod]
        public void FindWeakReferenceTest()
        {
            var item = new Item();
            var collection = new WeakReferenceCollection<Item>();
            collection.Add(item);
            collection.Contains(item).ShouldBeTrue();
            WeakReference weakReference = collection.FindWeakReference(item);
            weakReference.Target.ShouldEqual(item);

            item = null;
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            collection.Count.ShouldEqual(0);
            weakReference.IsAlive.ShouldBeFalse();
        }

        [TestMethod]
        public void FindWeakReferenceNullItem()
        {
            var collection = new WeakReferenceCollection<Item>();
            collection.FindWeakReference(new Item()).ShouldBeNull();
            collection.FindWeakReference(null).ShouldBeNull();
        }

        #region Overrides of CollectionTestBase

        protected override ICollection<T> CreateCollection<T>(params T[] items)
        {
            if (items.Length == 0)
                return new WeakReferenceCollection<T>();
            return new WeakReferenceCollection<T>(items);
        }

        #endregion
    }

    [TestClass]
    public class WeakReferenceCollectionSerializationTest : SerializationTestBase<WeakReferenceCollection<string>>
    {
        #region Overrides of SerializationTestBase

        public override void TestXmlSerialization()
        {
            //Not supported
        }

        public override WeakReferenceCollection<string> GetObject()
        {
            return new WeakReferenceCollection<string>(TestExtensions.TestStrings);
        }

        public override void AssertObject(WeakReferenceCollection<string> deserializedObj)
        {
            deserializedObj.SequenceEqual(TestExtensions.TestStrings).ShouldBeTrue();
        }

        #endregion
    }
}